package net.mycrub.bitwise.ocr.training;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import net.mycrub.bitwise.core.util.DeserializationException;
import net.mycrub.bitwise.core.util.Random;
import net.mycrub.bitwise.core.util.SerializationException;
import net.mycrub.bitwise.core.util.SerializationHelper;

public class ListOfBrainsDAO {

    public final static FileFilter FILE_FILTER = new BrainsFileFilter();
    public final String FILE_EXT = ".jar";
    
    private File dir;
    
    public File getDir() {
        return dir;
    }

    public void setDir(File dir) {
        this.dir = dir;
    }

    public void saveOrUpdate(ListOfBrains brains) throws SerializationException {
        if (brains == null) {
            throw new IllegalArgumentException("Can't save or update");
        }
        
        if (brains.id == null) {
            brains.id = System.nanoTime() + "-" + (long)(Random.next() * 1000000);
        }
        
        try {
            writeFile(brains);
        } catch (FileNotFoundException fnfe) {
            throw new SerializationException(fnfe);
        } catch (IOException ioe) {
            throw new SerializationException(ioe);
        }
    }
    
    private void writeFile(ListOfBrains brains) throws SerializationException, IOException {
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        try {
            fos = new FileOutputStream(dir.getAbsolutePath() + File.separator + brains.id + FILE_EXT);
            zos = new ZipOutputStream(fos);
            ZipEntry ze = new ZipEntry("brains.xml");
            ze.setMethod(ZipEntry.DEFLATED);
            zos.putNextEntry(ze);
            SerializationHelper.write(brains, zos);
        } catch (FileNotFoundException e) {
            throw new SerializationException(e);
        } finally {
            if (zos != null) {
                zos.closeEntry();
                zos.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }
    
    public String[] getAllIds() {
        File[] files = dir.listFiles(FILE_FILTER);
        String[] ids = new String[files.length];
        for (int i = 0; i < files.length; i++) {
            String fileName = files[i].getName(); 
            ids[i] = fileName.substring(0, fileName.length() - 4);
        }
        return ids;
    }
    
    public ListOfBrains get(String id) throws DeserializationException {
        FileInputStream fis = null;
        ZipInputStream zis = null;
        
        try {
            fis = new FileInputStream(dir.getAbsolutePath() + File.separator + id + FILE_EXT);
            zis = new ZipInputStream(fis);
            
            ZipEntry ze = null;
            while (!(ze = zis.getNextEntry()).getName().equals("brains.xml") && ze != null) {
            }
            
            return SerializationHelper.read(ListOfBrains.class, zis);
        } 
        catch (FileNotFoundException fnfe) {
            throw new DeserializationException(ListOfBrains.class, fnfe);
        }
        catch (IOException ioe) {
            throw new DeserializationException(ListOfBrains.class, ioe);
        }
    }

    
    //TODO remove(id)
    
}
